import {useElMessageBox} from '../hooks/useElMessageBox'
import axios, { AxiosError } from 'axios'
import { initRouterType, isFailCode, responseError } from './apiUtils'
import { httpConfig } from "@Tea/model"
import { useGloablLoading } from '../hooks'

export type HttpConfig = {
  url: string,
  method: string,
  params?: object | undefined,
  timeout?: number
  headers?: {
    'Content-Type': string
  },
  data?: object | undefined,
  extraConfig?: {
    [propName: string]: any
  },
  extraHeader?: {
    [propName: string]: any
  },
}
export type InitHttpReturnType<T = null> = {
  code: number,
  msg: string,
  data: T,
  total: number
}

export function initHttp(initConfig: initRouterType) {
  const requests = axios.create(httpConfig.createAxios)

  //请求拦截器
  requests.interceptors.request.use((config) => {
    return config
  })
  //响应拦截器
  requests.interceptors.response.use((resolve) => {
    const { code, msg } = resolve.data
    const { closeLoading } = useGloablLoading()
    if (isFailCode(code)) {
      useElMessageBox({
        content: msg,
        type: "error"
      })
      
      closeLoading()
    }
    
    return resolve.data
  }, (error: AxiosError) => {
    responseError(initConfig, error)
    return Promise.reject(error)
  })

  const http = <T = any>({ url, method, params, timeout = 20000, extraConfig, extraHeader }: HttpConfig):Promise<InitHttpReturnType<T>> => {
    const config: HttpConfig = {
      method,
      url,
      timeout,
      headers: {
        "Content-Type": "application/json", 
      },
    };
    method = method.toUpperCase();

    // 请求地址的添加时间戳，防止请求走缓存
    config.params = {
      ts: (new Date()).getTime()
    }
    if (method == "GET" || method == "DELETE") {
      config.params = Object.assign(params || { }, config.params);
    } else {
      config.data = params;
    }

    // 合并 config
    if (extraConfig) {
      Object.assign(config, extraConfig);
    }
    // 合并 headers
    if (extraHeader) {
      Object.assign(config.headers!, config.extraHeader)
    }
    
    return requests(config)
  }

  return http
}
